﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;

/**
 * Auth: Bjorn Carandang
 * Class for parsing HTML + CMS control markups into something
 * the Core can use to create HTML + live controls.
 * 
 * TODO: Salvage-proofing (key = "asdf>")
 * TODO: Specify compiled regexes
 * */

namespace RegexTestApplication
{
    class CMSTagParser
    {

        static String str_CMSTagRegex = "(?:(?:\\s*>)|(?:\\s+(?:[A-Za-z0-9]+\\s*=\\s*\"[A-Za-z0-9]+\"\\s*)*\\s*>))"; //The rest of a tag. See the constructor.

        static String str_KeyValuePairRegex = "[^=\\s]+\\s*=\\s*\"[A-Za-z0-9]+\"";

        static String str_KeyRegex = "([^=\\s]+(?=\\s*=\\s*))"; //The key in a key/value pair.

        static String str_ValueRegex = "(?<=\")\\w+(?=\")"; //The value in a key/value pair.

        //On slurped text, if there is also a left bracket, accept at zero-width.
        static String str_TagRegex = "((?<=<\\s*)[A-Za-z0-9]+)";

        static Regex KeyValuePairRegex = new Regex(str_KeyValuePairRegex);
        static Regex KeyRegex = new Regex(str_KeyRegex);
        static Regex ValueRegex = new Regex(str_ValueRegex);
        static Regex TagRegex = new Regex(str_TagRegex);

        Regex CMSTagParserRegex;
    
        /*
         *Takes list of prefixes, creates extremely large OR junction out of them,
         *tacks it onto the beginning of the CMSTagRegex.
         */
        public CMSTagParser(List<String> prefixes)
        {
            String s = "";
            for(int i = 0; i < prefixes.Count; i++)
            {
                s += prefixes[i];
                if (i < prefixes.Count - 1)
                {
                    s += "|";
                }
            }
            //Huge unslurped OR junction, then the criterion for a bunch of key/value pairs.
            String finalregex = "<(?:" + s + ")" + str_CMSTagRegex;
            CMSTagParserRegex = new Regex(finalregex, RegexOptions.IgnoreCase);
        }

        //Given file as string, return mixed list of Strings and
        //CMSTags.
        public List<Object> ParseTags(String s)
        {
            String buffer = s.Substring(0, s.Length);
            List<Object> returnList = new List<Object>();

            while (buffer.Length > 0 && CMSTagParserRegex.IsMatch(buffer))
            {
                Match match = CMSTagParserRegex.Match(buffer);
                string[] splitpoint = CMSTagParserRegex.Split(buffer, 2);
                if (splitpoint[0].Length != 0) returnList.Add(splitpoint[0]);
                    returnList.Add(ParseObject(match.Value));

                        buffer = splitpoint[1];

                    Console.WriteLine(buffer);

            }
            return returnList;
            //String[] things = CMSTagParserRegex.Split(s);
            //MatchCollection matches = CMSTagParserRegex.Matches(s);

            //foreach (Match m in matches)
            //{
            //    Console.WriteLine(m.Value);
            //}

            //foreach (String str in things)
            //{
            //    Console.WriteLine(str);
            //}
            
            //for(int i = 0; i < matches.Count; i++)
            //{
            //    //A shuffle.
            //    if(things[i] != String.Empty) returnList.Add(things[i]);
            //    returnList.Add(ParseObject(matches[i].Value));
            //}
            //return returnList;
        }

        //Split individual tag into leading tag, and then into key/value pairs.
        public CMSTag ParseObject(String s)
        {
            MatchCollection keyvalue = KeyValuePairRegex.Matches(s);
            ArrayList keys = new ArrayList();
            ArrayList values = new ArrayList();
            String tag = TagRegex.Match(s).Value;

            foreach (Match keypair in keyvalue)
            {
                keys.Add(KeyRegex.Match(keypair.Value).Value);
                values.Add(ValueRegex.Match(keypair.Value).Value);
            }

            return new CMSTag(tag, keys, values);
        }

    }
}
